// menu.service.ts
import {
  BadRequestException,
  Injectable,
  NotFoundException,
} from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Menu } from '../../entities/menu.entity';
import { IsNull, NamingStrategyInterface, Repository } from 'typeorm';
import {
  DeleteMenuDto,
  MenuWithChildrenDto,
  PageMenuDto,
} from '../../dto/menu/menu.dto';
import { plainToClass } from 'class-transformer';
import { PageOptionsDto } from '../../dto/page.dto';
@Injectable()
export class MenuService {
  constructor(
    @InjectRepository(Menu)
    private menuRepository: Repository<Menu>,
  ) {}
  //获取所有菜单
  async getAllMenus(): Promise<Menu[]> {
    const menus = await this.menuRepository.find({
      relations: ['children'],
      order: {
        sortNo: 'ASC', // 根据 sortNo 升序排序
      },
    });

    return menus;
  }
  // 分页条件查询
  async getMenusWithPageOptions(
    pageOptions: PageMenuDto,
  ): Promise<[Menu[], number]> {
    const { pageSize, pageNo, name } = pageOptions;
    // const where = { ...pageOptions, parentId: IsNull() };
    // delete where.pageSize;
    // delete where.pageNo;
    const [parentMenus, total] = await this.menuRepository.findAndCount({
      take: pageSize,
      skip: (pageNo - 1) * pageSize,
      where: {
        name,
        parentId: IsNull(),
      },
      order: { sortNo: 'ASC' },
      relations: ['children'], // 加载子菜单关系
    });

    return [parentMenus, total];
  }
  // 创建菜单
  async create(createMenuDto: Menu): Promise<Menu> {
    const { parentId, ...menuData } = createMenuDto;

    const parentMenu = parentId
      ? await this.menuRepository.findOne({ where: { id: parentId } })
      : null;

    const menu = this.menuRepository.create({
      ...menuData,
      parentId: parentMenu as any,
    });
    if (!parentId) {
      menu.parentId = null;
    }

    console.log(menu, 'menu');

    return this.menuRepository.save(menu);
  }
  // 更新菜单，涉及父子关系
  async updateMenu(id: string, updateMenuDto: Menu): Promise<Menu> {
    const menu = await this.menuRepository.findOne({
      where: { id },
      relations: ['parent'], // 加载父菜单关系
    });

    if (!menu) {
      throw new NotFoundException(`此 ID${id} 不存在`);
    }

    // 检查新的 parent 是否存在于 menu 表中
    const newParentId = updateMenuDto.parentId;
    if (newParentId) {
      const isValidParent = await this.menuRepository.findOne({
        where: { id: newParentId },
      });
      if (!isValidParent) {
        throw new BadRequestException(`无效的 parent: ${newParentId}`);
      }
      if (updateMenuDto.parentId == id) {
        throw new BadRequestException(
          `无效的 parent: ${newParentId},parentId不能跟id相同`,
        );
      }
    }

    // 更新基本属性
    Object.assign(menu, updateMenuDto);

    // 更新父子关系
    if (newParentId !== menu.parentId) {
      const newParent = await this.menuRepository.findOne({
        where: { parentId: newParentId },
      });

      menu.parentId = newParent as any;
    }

    return this.menuRepository.save(menu);
  }

  // 删除菜单
  async deleteMenu(id: string): Promise<void> {
    const menu = await this.menuRepository.findOne({
      where: { id },
      relations: ['children'], // 加载子菜单关系
    });

    if (!menu) {
      throw new NotFoundException(`此 ID${id} 不存在`);
    }

    // if (menu.children && menu.children.length > 0) {
    //   throw new BadRequestException('存在子菜单，无法删除');
    // }

    await this.menuRepository.remove(menu);
  }

  // 查询所有菜单
  private async getMenuTree(): Promise<any[]> {
    const menus = await this.menuRepository.find();

    const processedMenus = menus.map((menu) => this.convertMenuToJSON(menu));

    return processedMenus;
  }
  // 将扁平的菜单数组转换为菜单树
  buildMenuTree(flatMenus: Menu[], isMenu?: boolean): MenuWithChildrenDto[] {
    const menuTree: MenuWithChildrenDto[] = [];

    const convertToCamelCase = (obj: any): any => {
      console.log('Original Object:', obj);
      const result = isMenu ? this.convertMenuToJSON(obj) : obj;
      console.log('Converted Object:', result);
      return result;
    };

    const findChildren = (parentId: string): MenuWithChildrenDto[] => {
      const children: MenuWithChildrenDto[] = [];

      for (const menu of flatMenus) {
        if (menu.parentId === parentId) {
          const convertedMenu = convertToCamelCase(menu);
          convertedMenu.children = findChildren(menu.id); // 递归查找子菜单

          children.push(convertedMenu);
        }
      }

      return children;
    };

    // 查找顶级菜单
    for (const menu of flatMenus) {
      if (!menu.parentId) {
        const convertedTopMenu = convertToCamelCase(menu);
        convertedTopMenu.children = findChildren(menu.id); // 递归查找子菜单

        menuTree.push(convertedTopMenu);
      }
    }

    return menuTree;
  }
  // 递归处理菜单项
  private processMenu(menu: Menu): Menu {
    // 处理当前菜单项的 meta 字段等
    const result: any = {
      name: menu.name || '',
      id: menu.id || null,
      redirect: menu.redirect || null,
      path: menu.url,
      component: menu.component || null,
      route: menu.url,
      meta: {
        keepAlive: menu.keepAlive || false,
        componentName: menu.componentName,
        title: menu.name,
      },
    };

    // 递归处理子菜单
    if (menu.children && menu.children.length > 0) {
      // 创建新的子菜单数组，避免修改原始数组
      result.children = menu.children.map((childMenu) =>
        this.processMenu(childMenu),
      );
    }

    return result;
  }

  //转成路由模式菜单
  convertMenuToJSON = (menu: MenuWithChildrenDto): any => {
    const result: any = {
      name: menu.name || '',
      id: menu.id || null,
      parentId: menu.parentId || null,
      redirect: menu.redirect || null,
      path: menu.url,
      component: menu.component || null,
      route: menu.url,
      meta: {
        keepAlive: menu.keepAlive || false,
        componentName: menu.componentName,
        title: menu.name,
      },
    };

    if (menu.children && menu.children.length > 0) {
      result.children = menu.children.map((child) =>
        this.convertMenuToJSON(child),
      );
    }

    return result;
  };
}
